#pragma once
#include "common.h"
#include "buffer.h"
#include "config.h"

enum class CacheReqCmd
{
    NOP,
    LOAD,
    STORE,
    MMIO,
    LR_SC,
    ATOMICS
};

class CacheOP
{
public:
    CacheReqCmd cmd;
    uint64_t id;
    word_t addr;
    size_t size;
};

class CacheRecvInterface {
public:
    virtual bool recv(CacheOP *cop) = 0;
};

class Cache
{
public:
    virtual void run() = 0;
    virtual void reset() = 0;
    virtual bool send(CacheOP *cop) = 0;
    CacheRecvInterface *recv;
};

class NormalCache : public Cache
{
    uint64_t cycle;
    uint64_t latency;
    typedef std::tuple<CacheOP*, uint64_t> NormalCacheOP;
    FIFO<NormalCacheOP> ops;
    bool has_send;
public:
    NormalCache();
    ~NormalCache() = default;
    void run() override;
    void reset() override;
    bool send(CacheOP *cop) override;
};
